#include "workqueue.h"

static struct workqueue_struct *radaTransmit;
static rwlock_t status = RW_LOCK_UNLOCKED;

static void pf_transmitPacket( struct work_struct *work ) {	
        pf_transmit *todo = (pf_transmit *) work;
	// odosleme klasickou metodou
	pf_send_data_workqueue(todo->dest, todo->buf, todo->len);
        printk(KERN_INFO "DBG: transmit paketu naplanovany\n");
	kfree( todo->buf );
        kfree( (void *) todo );
        return;
}

static void pf_transmitHello( struct work_struct *work ) {
        pf_transmit *todo = (pf_transmit *) work;
        // odosleme klasickou metodou
        pf_send_hello_workqueue(todo->buf, todo->len);
//	phs_sendHello(todo->buf, todo->len);
        printk(KERN_INFO "DBG: transmit Hello paketu naplanovany\n");
        kfree( (SwapPacket *) todo->buf );
        kfree( (void *) todo );
        return;
}

void naplanujOdoslaniePDU(uint32_t dest, char *buf, int len) {
        pf_transmit *uloha = NULL;
        int ret;
	char *data;
	read_lock(&status);
	// ak existuje pracovna rada pre Odosielanie tak vytvor ulohu
	// moze nastat aj to ze sme ju uz zrusili, tym padom sa deinicializuje
	// modul a nie je dovod posielat dalsie pakety
	if (radaTransmit) {
        	uloha = (pf_transmit *) kmalloc(sizeof(pf_transmit), GFP_KERNEL);
		data = (char *) kmalloc(len, GFP_KERNEL);
	}
        if (uloha && data) {
		memcpy(data, buf, len);
                INIT_WORK( (struct work_struct *) uloha, pf_transmitPacket);
                uloha->dest = dest;
                uloha->buf = data;
                uloha->len = len;
                ret = queue_work( radaTransmit, (struct work_struct *) uloha);
        }
        else {
		printk(KERN_ERR "pokaslala sa alokacia pamati pri naplanovaniPDU\n");
	}
	read_unlock(&status);
	return;
}


void naplanujOdoslanieHello(char *buf, int len) {
        pf_transmit *uloha = NULL;
        int ret;
        char *data;
	read_lock(&status);
        // ak existuje pracovna rada pre Odosielanie tak vytvor ulohu
        // moze nastat aj to ze sme ju uz zrusili, tym padom sa deinicializuje
        // modul a nie je dovod posielat dalsie pakety
        if (radaTransmit) {
                uloha = (pf_transmit *) kmalloc(sizeof(pf_transmit), GFP_ATOMIC);
                data = (char *) kmalloc(len, GFP_ATOMIC);
        }
        if (uloha && data) {
                memcpy(data, buf, len);
                INIT_WORK( (struct work_struct *) uloha, pf_transmitHello);
                uloha->dest = 0;
                uloha->buf = data;
                uloha->len = len;
                ret = queue_work( radaTransmit, (struct work_struct *) uloha);
        }
        else {
                printk(KERN_ERR "pokaslala sa alokacia pamati pri naplanovaniHello\n");
        }
	read_unlock(&status);
        return;
}

int inicializujTransmitQueue( void ) {
  radaTransmit = create_workqueue("PF_TransmitQueue");
  if (radaTransmit) {
        printk(KERN_INFO "DBG: TransmitQueue inicializovana\n");
        return 0;
  }
  return -1;
}

int zmazTransmitQueue( void ) {
	write_lock(&status);
        flush_workqueue( radaTransmit );
        destroy_workqueue( radaTransmit );
	write_unlock(&status);
        printk(KERN_INFO "DBG: TransmitQueue zrusena\n");
        return 1;
}
